package org.apache.struts.ehr.medical_records.action;

import java.util.ArrayList;
import java.util.Date;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts.ehr.medical_records.model.Bht;
import org.apache.struts.ehr.medical_records.model.GuardianForPatientDetails;
import org.apache.struts.ehr.medical_records.model.MedicalRecords;
import org.apache.struts.ehr.medical_records.model.OldAdmissions;
import org.apache.struts.ehr.medical_records.model.PatientRecords;
import org.apache.struts.ehr.medical_records.model.Query;
import org.apache.struts.ehr.medical_records.model.ReplyMessage;
import org.apache.struts2.interceptor.ServletRequestAware;

import ca.uhn.hl7v2.HL7Exception;
import ca.uhn.hl7v2.model.v21.datatype.TS;
import ca.uhn.hl7v2.model.v251.datatype.DTM;
import ca.uhn.hl7v2.model.v251.datatype.XAD;
import ca.uhn.hl7v2.model.v251.datatype.XTN;
import ca.uhn.hl7v2.model.v251.message.ADR_A19;
import ca.uhn.hl7v2.model.v251.segment.DG1;
import ca.uhn.hl7v2.model.v251.segment.NK1;
import ca.uhn.hl7v2.model.v251.segment.OBX;
import ca.uhn.hl7v2.model.v251.segment.PID;
import ca.uhn.hl7v2.model.v251.segment.PV1;
import ca.uhn.hl7v2.model.v251.segment.PV2;

import com.earogya.communicate.Communicator;
import com.earogya.logic.medical_records.CreateQRYA19;
import com.earogya.logic.medical_records.ParseReply;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

public class ViewOldAdmissionsAction extends ActionSupport implements ServletRequestAware{

	private HttpServletRequest request;
	private ArrayList<OldAdmissions> oldAdmissionRecords=new ArrayList<OldAdmissions>();
	private ReplyMessage replyMessage;
	
	public ReplyMessage getReplyMessage() {
		return replyMessage;
	}

	public ArrayList<OldAdmissions> getOldAdmissionRecords() {
		return oldAdmissionRecords;
	}

	public void setServletRequest(HttpServletRequest arg0) {
		this.request = arg0;
	}

	public String execute()throws Exception{
		Map<String, Object> session=ActionContext.getContext().getSession();
		replyMessage=new ReplyMessage();
		replyMessage.setMessage("empty");
		Query query=new Query();
		query.setPatientId(request.getParameter("patient_id"));
		query.setSearch_type("old admissions");
		CreateQRYA19 createMessage=new CreateQRYA19(query);
		String msg=createMessage.createMessage("CSTH");
		if(!msg.equals(null)){
			Communicator c=new Communicator();
			String reply=c.sendMessage(msg);
			if(!reply.equals("No Reply")){
				ParseReply parse=new ParseReply();
				try{
					ADR_A19 adr=(ADR_A19)parse.parseMessage(reply);
					this.setValuesToAdmission(adr);
				}catch(ClassCastException e){
					replyMessage=(ReplyMessage)parse.parseMessage(reply);
				}
			}
		}
		else{
			
		}
		return SUCCESS;
	}
	
	private void setValuesToAdmission(ADR_A19 adr) throws HL7Exception{
		for(int r=0; r<adr.getQUERY_RESPONSEReps(); r++){
			OldAdmissions records=new OldAdmissions();
			PID pid=adr.getQUERY_RESPONSE(r).getPID();
			records.setPatient_id(pid.getPatientID().getIDNumber().getValue());
			
			PV1 pv1=adr.getQUERY_RESPONSE(r).getPV1();
			records.setAdmission_date(pv1.getAdmitDateTime().getTime().getValueAsDate());
			records.setAdmiting_officer(pv1.getAdmittingDoctor(0).getIDNumber().getValue());
			records.setBed(pv1.getPriorPatientLocation().getBed().getValue());
			records.setWard(pv1.getPriorPatientLocation().getRoom().getValue());
			DTM t=pv1.getDischargeDateTime(0).getTime();
			if(t!=null){
				records.setDischarge_date(pv1.getDischargeDateTime(0).getTime().getValueAsDate());
				records.setComments(pv1.getDischargeDisposition().getValue());
			}
			Bht bht=new Bht();
			bht.setCurrent_bed(pv1.getAssignedPatientLocation().getBed().getValue());
			bht.setCurrent_ward(pv1.getAssignedPatientLocation().getRoom().getValue());
			bht.setConsultant_id(pv1.getConsultingDoctor(0).getIDNumber().getValue());
			records.setBht(bht);
			
			PV2 pv2=adr.getQUERY_RESPONSE(r).getPV2();
			records.setAdmit_reason(pv2.getAdmitReason().getText().getValue());
			
			int numberOfObservations=adr.getQUERY_RESPONSE(r).getOBXReps();
			int numberOfDiagonosis=adr.getQUERY_RESPONSE().getDG1Reps();
			int maxLength=numberOfDiagonosis;
			if(numberOfObservations>numberOfDiagonosis){
				maxLength=numberOfObservations;
			}
			ArrayList<MedicalRecords> medicalRecordsList=new ArrayList<MedicalRecords>();
			for(int i=0; i<maxLength; i++){
				MedicalRecords medicalRecords=new MedicalRecords();
				if(i<numberOfObservations){
					OBX obx=adr.getQUERY_RESPONSE(r).getOBX(i);
					medicalRecords.setObservation(obx.getObservationValue(0).getData().encode());
					medicalRecords.setObserverId(obx.getResponsibleObserver(0).getIDNumber().getValue());
					medicalRecords.setObservationdate(obx.getDateTimeOfTheObservation().getTime().getValueAsDate());
				}
				else{
					medicalRecords.setObservation("");
					medicalRecords.setObserverId("");
					medicalRecords.setObservationdate(new Date());
				}
				if(i<numberOfDiagonosis){
					DG1 dg1=adr.getQUERY_RESPONSE(r).getDG1(i);
					medicalRecords.setDiagosis(dg1.getDiagnosisDescription().getValue());
					medicalRecords.setDiagnosingClinicianId(dg1.getDiagnosingClinician(0).getIDNumber().getValue());
					medicalRecords.setDiagnosingDate(dg1.getDiagnosisDateTime().getTime().getValueAsDate());
				}
				else{
					medicalRecords.setDiagosis("");
					medicalRecords.setDiagnosingClinicianId("");
					medicalRecords.setDiagnosingDate(new Date());
				}
				medicalRecordsList.add(medicalRecords);
			}
			records.setMedicalRecords(medicalRecordsList);
			
			GuardianForPatientDetails guardian=new GuardianForPatientDetails();
			NK1 nk1=adr.getQUERY_RESPONSE(r).getNK1();
			guardian.setPrefix(nk1.getNK1Name(0).getPrefixEgDR().getValue());
			guardian.setGiven_name(nk1.getNK1Name(0).getGivenName().getValue());
			guardian.setFurthur_names(nk1.getNK1Name(0).getSecondAndFurtherGivenNamesOrInitialsThereof().getValue());
			guardian.setSurname(nk1.getNK1Name(0).getFamilyName().getSurname().getValue());
			guardian.setNic_no(nk1.getContactPersonSocialSecurityNumber().getValue());
			guardian.setGuardian_relationship(nk1.getRelationship().getText().getValue());
			
			ArrayList<org.apache.struts.ehr.medical_records.model.Address> addressList=new ArrayList<org.apache.struts.ehr.medical_records.model.Address>();
			XAD[] addresses=nk1.getAddress();
			for(int i=0; i<addresses.length; i++){
				org.apache.struts.ehr.medical_records.model.Address address=new org.apache.struts.ehr.medical_records.model.Address();
				address.setHouse_number(addresses[i].getStreetAddress().getDwellingNumber().getValue());
				address.setStreet(addresses[i].getStreetAddress().getStreetName().getValue());
				address.setCity_1(addresses[i].getOtherDesignation().getValue());
				address.setCity_2(addresses[i].getCity().getValue());
				address.setCountry(addresses[i].getCountry().getValue());
				addressList.add(address);
			}
			guardian.setAddresses(addressList);
			
			ArrayList<String> telephoneNumberList=new ArrayList<String>();
			ArrayList<String> emailList=new ArrayList<String>();
			XTN[] telephoneNumbers=nk1.getPhoneNumber();
			for(int i=0; i<telephoneNumbers.length; i++){
				telephoneNumberList.add(telephoneNumbers[i].getTelephoneNumber().getValue());
				if(telephoneNumbers[i].getEmailAddress()!=null){
					emailList.add(telephoneNumbers[i].getEmailAddress().getValue());
				}
			}
			guardian.setTelephoneNumbers(telephoneNumberList);
			guardian.setEmail(emailList);
			records.setGuardian(guardian);
			oldAdmissionRecords.add(records);
		}
	}
}
